package com.liaoyin.travel.service.attendance;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liaoyin.travel.dao.attendance.AttendanceUserMapper;
import com.liaoyin.travel.view.mine.attendance.AttendanceManagementView;
import com.liaoyin.travel.view.moble.attendance.ClockSettingsView;
import com.liaoyin.travel.view.user.UserView;
import com.liaoyin.travel.view.travelMobileControlSystem.AttendanceView;
import com.liaoyin.travel.vo.attendance.AttendanceManageVo;
import com.liaoyin.travel.vo.attendance.AttendanceManagementVo;
import com.liaoyin.travel.vo.attendance.AttendanceOldUser;
import com.liaoyin.travel.vo.attendance.InsertOrUpdateAttendanceManagementVo;
import com.liaoyin.travel.base.constant.VariableConstants;
import com.liaoyin.travel.base.service.BaseService;
import com.liaoyin.travel.bean.UserInfo;
import com.liaoyin.travel.dao.attendance.AttendanceManagementMapper;
import com.liaoyin.travel.entity.FileUpload;
import com.liaoyin.travel.entity.Users;
import com.liaoyin.travel.entity.attendance.AttendanceManagement;
import com.liaoyin.travel.entity.attendance.AttendanceUser;
import com.liaoyin.travel.exception.BusinessException;
import com.liaoyin.travel.service.UsersService;
import com.liaoyin.travel.util.FileUploadUtil;
import com.liaoyin.travel.util.PartyUtil;
import com.liaoyin.travel.util.SnowIdUtil;
import com.liaoyin.travel.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 考勤管理 service
 *
 * @author Kuang.JiaZhuo
 * @date 2019-11-18 14:06
 */
@Service
public class ManagementService extends BaseService<AttendanceManagementMapper, AttendanceManagement> {

    @Autowired
    private AttendanceUserService attendanceUserService;

    @Autowired
    private AttendanceWorkdayService attendanceWorkdayService;

    @Autowired
    private UsersService usersService;

    @Resource
    AttendanceUserMapper attendanceUserMapper;

    /**
     * @方法名：insertOrUpdateAttendanceManagement
     * @描述： 新增或修改考勤管理
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/18 14:24
     */
    @Transactional(rollbackFor = Exception.class)
    public int insertOrUpdateAttendanceManagement(InsertOrUpdateAttendanceManagementVo insertOrUpdateAttendanceManagementVo) {
        //获取到用户的登录信息,判断用户是否登录
        UserInfo user = PartyUtil.getCurrentUserInfo();
        if(user == null) {
            throw new BusinessException("user.isNotLogin");
        }
        /** 景区id */
        String scenicId = user.getScenicId();

        //考勤工作日的字符串集
        String attendanceDays = insertOrUpdateAttendanceManagementVo.getAttendanceDays();

        //考勤名称
        String checkingInName = insertOrUpdateAttendanceManagementVo.getCheckingInName().trim();

        /** 有效性验证 */
        AttendanceManagement attendanceManagement = new AttendanceManagement();
        attendanceManagement.setEquipmentId(insertOrUpdateAttendanceManagementVo.getEquipmentId())
                .setAttendanceStartTime(LocalTime.parse(insertOrUpdateAttendanceManagementVo.getAttendanceStartTime()))
                .setAttendanceEndTime(LocalTime.parse(insertOrUpdateAttendanceManagementVo.getAttendanceEndTime()))
                .setAttendanceRange(insertOrUpdateAttendanceManagementVo.getAttendanceRange())
                .setCheckingInName(checkingInName)
                .setParticipantId(insertOrUpdateAttendanceManagementVo.getParticipantId())
                .setAttendanceDays(attendanceDays);

        //考勤开始时间
        LocalTime attendanceStartTime = attendanceManagement.getAttendanceStartTime();
        //考勤结束时间
        LocalTime attendanceEndTime = attendanceManagement.getAttendanceEndTime();
        //考勤开始时间不能大于考勤结束时间
        if(attendanceStartTime.isAfter(attendanceEndTime)){
            throw new BusinessException("startTime.isAfter.endTime");
        }
        //参与考勤人员的id字符串集
        String participantId = attendanceManagement.getParticipantId();

        //返回结果
        int result = 0;
        String id = insertOrUpdateAttendanceManagementVo.getId();

        if(id==null || "".equals(id)){
            /** 新增 */

            /** 2019-11-19和@汪沙沱确定逻辑 一个人只能绑定一个考勤名称*/

            //考勤名称、考勤组用户不能重复
            judgementAttendanceRepeated(checkingInName,participantId,null,scenicId);

            //雪花算法生成主键
            id = SnowIdUtil.getInstance().nextId();
            attendanceManagement.setId(id)
                    //创建人id
                    .setCteateById(user.getId())
                    //创建时间
                    .setCreateTime(LocalDateTime.now())
                    //默认未启用，新增后再进行启用的操作
                    .setIsUsing(VariableConstants.STRING_CONSTANT_0)
                    //默认未删除
                    .setIsDelete(VariableConstants.STRING_CONSTANT_0)
                    //景区id
                    .setScenicId(scenicId);
            if(StringUtil.isNotEmpty(insertOrUpdateAttendanceManagementVo.getIsUsing())){
                attendanceManagement.setIsUsing(insertOrUpdateAttendanceManagementVo.getIsUsing());
            }
            result = this.mapper.insertSelective(attendanceManagement);
            System.err.println(attendanceManagement);
            if(result>0){
                //新增 考勤管理-用户关联
                this.attendanceUserService.insertOrUpdateAttendanceUser(scenicId,participantId,id,1);
                //新增 考勤-工作日
                this.attendanceWorkdayService.insertOrUpdateAttendanceWorks(scenicId,attendanceDays,id,1);
            }
        }else{
            /** 更新 */
            //考情名称、考勤组用户不能重复
            judgementAttendanceRepeated(checkingInName,participantId,id,scenicId);

            attendanceManagement.setId(id)
                    //更新人id
                    .setUpdateById(user.getId())
                    //更新时间
                    .setUpdateTime(LocalDateTime.now())
                    //是否删除
                    .setIsDelete(insertOrUpdateAttendanceManagementVo.getIsDelete())
                    //是否启用
                    .setIsUsing(insertOrUpdateAttendanceManagementVo.getIsUsing());
            result = this.mapper.updateById(attendanceManagement);
            //更新 考勤管理-用户关联
            this.attendanceUserService.insertOrUpdateAttendanceUser(scenicId,participantId,id,2);
            //更新 考勤-工作日
            this.attendanceWorkdayService.insertOrUpdateAttendanceWorks(scenicId,attendanceDays,id,2);

            System.err.println(attendanceManagement);
        }
        return result;
    }

    /**
     * @方法名：judgementAttendanceRepeated
     * @描述： 判断考勤名称、考勤组用户不能重复，若重复抛出异常
     * @作者： kjz
     * @日期： Created in 2020/4/5 22:31
     */
    public void judgementAttendanceRepeated(String checkingInName, String participantId, String id,String scenicId) {
        System.err.println("checkingInName="+checkingInName);
        System.err.println("id="+id);
        System.err.println("participantId="+participantId);
        System.err.println("scenicId="+scenicId);
        Integer count = this.mapper.selectCountByCheckingInName(checkingInName,id,scenicId);
        if(count>0){
            throw new BusinessException("attendance.name.repetition");
        }
        String[] idStringArray = participantId.split(",");
        List<String> participantIdList = Arrays.asList(idStringArray);
        for (String userId:participantIdList) {
            AttendanceOldUser attendanceOldUser = this.attendanceUserMapper.selectAttendanceUserByUserIdAndAttendanceId(userId,id);
            if(attendanceOldUser!=null){
                String userName = attendanceOldUser.getUserName();
                String oldCheckingInName = attendanceOldUser.getCheckingInName();
                String info = "用户【"+userName+"】已经加入【"+oldCheckingInName+"】考勤组,不能重复添加";
                throw new BusinessException("attendanceUsers.is.repetition",info);
            }
        }

    }

    /**
     * @方法名：judgeClockTimeConflict
     * @描述： 判断打卡时间设置是否存在冲突，有冲突就抛出异常
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/19 16:40
     */
    private void judgeClockTimeConflict(List<AttendanceOldUser> oldUserList) {
        if(oldUserList.size()>0){
            //oldUserList 以考勤名分组 Map<String,List<Apple>>
            Map<String, List<AttendanceOldUser>> groupBy = oldUserList
                    .stream().collect(Collectors.groupingBy(AttendanceOldUser::getCheckingInName));
            //取出第一个key值
            String key = null;
            for (Map.Entry<String, List<AttendanceOldUser>> entry : groupBy.entrySet()) {
                key = entry.getKey();
                if (key != null) {
                    break;
                }
            }
            //取出第一个value值
            List<AttendanceOldUser> firstUserList = new ArrayList<>();
            for (Map.Entry<String, List<AttendanceOldUser>> entry : groupBy.entrySet()) {
                firstUserList = entry.getValue();
                if (firstUserList.size()>0) {
                    break;
                }
            }
            String hint = "用户 ";
            //组装拼接提示结果
            for(AttendanceOldUser attendanceOldUser:firstUserList){
                hint += attendanceOldUser.getUserName()+"、";
            }
            hint = hint.substring(0,hint.length() -1);
            hint = hint+" 已经加入了考勤点【"+key+"】,不能重复设置";
            BusinessException exception = new BusinessException("Clock time conflict");
            exception.setDesc(hint);
            throw exception;

        }
    }

    /**
     * @方法名：deleteAttendanceManagementByIds
     * @描述： 根据ids字符串批量(物理)删除考勤管理
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/18 17:28
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteAttendanceManagementByIds(String ids) {
        String[] idStringArray = ids.split(",");
        List<String> isList = Arrays.asList(idStringArray);
        int result = 0;
        for(String id:isList){
            result += this.mapper.deleteAttendanceManagementById(id);
            if(result>0){
                this.attendanceUserService.deleteAttendanceUsersByAttendanceId(id);
            }
        }
        return result;
    }

    /**
     * @方法名：selectAttendanceManagementViewByCondition
     * @描述： 后台-按条件查询考勤管理(带分页)
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/18 18:07
     */
    public PageInfo<AttendanceManagementView> selectAttendanceManagementViewByCondition(AttendanceManagementVo attendanceManagementVo) {
        UserInfo curveUserInfo = PartyUtil.getCurrentUserInfo();
        if(curveUserInfo == null) {
            throw new BusinessException("not.login");
        }
        /** 景区id */
        String scenicId = curveUserInfo.getScenicId();
        attendanceManagementVo.setScenicId(scenicId);
        PageHelper.startPage(attendanceManagementVo.getNum(),attendanceManagementVo.getSize());
        List<AttendanceManagementView> list = this.mapper.selectAttendanceManagementViewByCondition(attendanceManagementVo);
        PageInfo<AttendanceManagementView> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    /**
     * @方法名：getAttendanceViewList
     * @描述： 查询旅游云移动管控系统考勤信息新增接口需要的数据(带分页)
     * @作者： kjz
     * @日期： Created in 2020/3/31 11:09
     */
    public List<AttendanceView> getAttendanceViewListByPage(Integer num,Integer size){
        PageHelper.startPage(num,size);

        List<AttendanceView> list = this.getAttendanceViewList();

        return list;
    }

    /**
     * @方法名：getAttendanceViewList
     * @描述： 查询旅游云移动管控系统考勤信息新增接口需要的数据
     * @作者： kjz
     * @日期： Created in 2020/3/31 15:34
     */
    public List<AttendanceView> getAttendanceViewList() {
        List<AttendanceView> list = this.mapper.getAttendanceViewList();
        list.forEach(attendanceView -> {
            String attendanceId = attendanceView.getAttendanceId();
            //没有参与考勤的人员就填无
            String peoples = this.mapper.selectUserNamesByAttendanceId(attendanceId);
            peoples = peoples==null?"无":peoples;
            //格式化日期
            String workeday = attendanceView.getWorkeday();
            workeday = formatWorkeday(workeday);
            attendanceView.setPeoples(peoples).setWorkeday(workeday);
        });
        return list;
    }

    /**
     * @方法名：formatWorkeday
     * @描述： 格式化考勤日期
     * @作者： kjz
     * @日期： Created in 2020/3/31 15:03
     */
    public String formatWorkeday(String workeday) {
        Map<String,String> map = new HashMap<>();
        map.put("1","一");
        map.put("2","二");
        map.put("3","三");
        map.put("4","四");
        map.put("5","五");
        map.put("6","六");
        map.put("7","日");

        String result = "";
        List<String> workList = Arrays.asList(workeday.split(","));
        if(workList.size()==7){
            result = "周一至周日";
        }else{
            for(String workDay:workList){
                result += "周"+map.get(workDay)+",";
            }
            //去掉最后一个字符串
            result = result.substring(0, result.length() - 1);
        }

        return result;
    }

    public AttendanceManagement getById(String id){
        return this.mapper.selectAttendanceManagementById(id);
    }

    /**
     * @方法名：selectAttendanceManagementById
     * @描述： 后台-根据id查询考勤管理详情
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/18 19:29
     */
    public AttendanceManagement selectAttendanceManagementById(String id) {
        AttendanceManagement attendanceManagement = this.mapper.selectAttendanceManagementById(id);
        if(attendanceManagement==null){
            return null;
        }
        /** 考勤&星期 */

        /** 参与考勤的人员 */
        List<AttendanceUser> attendanceUserList = this.attendanceUserService.selectAttendanceUserByAttendanceId(attendanceManagement.getId());
        List<String> userIdList = new ArrayList<>();
        attendanceUserList.forEach(attendanceUser -> {
            userIdList.add(attendanceUser.getUserId());
            System.err.println(attendanceUser.getUserId());
        });
        System.err.println(userIdList.size());
        List<Users> usersList = this.usersService.selectUsersByIds(userIdList);

        List<UserView> userViews = new ArrayList<>();
        if(usersList!=null && !usersList.isEmpty()){
            usersList.forEach(users -> {
                UserView userView = new UserView();
                String userId = users.getId();
                String nickName = users.getNickName();
                //头像
                String headPicId = users.getHeadPicId();
                FileUpload fileUpload = FileUploadUtil.getFileUpload(headPicId);
                String headPicUrl = null;
                if(fileUpload!=null){
                    headPicUrl = fileUpload.getUrl();
                }
                System.err.println("headPicUrl="+headPicUrl);
                userView.setHeadPicUrl(headPicUrl);
                //职务
                String holdOffice = users.getAssumeOfficeDisplay();
                userView.setHoldOffice(holdOffice);
                userView.setUserId(userId);
                userView.setNickName(nickName);
                userViews.add(userView);
            });
        }
        attendanceManagement.setAttendancePersonnel(userViews);
        return attendanceManagement;
    }

    /**
     * @方法名：selectAttendanceManageVoByUserId
     * @描述： 通过用户id查询此用户的考勤打卡设置信息
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/20 10:54
     */
    public AttendanceManageVo selectAttendanceManageVoByUserId(String userId) {
        if(userId==null){
            UserInfo user = PartyUtil.getCurrentUserInfo();
            if(user == null) {
                throw new BusinessException("user.isNotLogin");
            }
            userId = user.getId();
        }

        AttendanceManageVo attendanceManageVo = this.mapper.selectAttendanceManageVoByUserId(userId);
        return attendanceManageVo;
    }

    /**
     * @方法名：selectClockSettingsViewByUserID
     * @描述： 查询员工打卡的考勤设置信息
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/22 14:42
     */
    public ClockSettingsView selectClockSettingsViewByUserID(String userId) {
        ClockSettingsView clockSettingsView = this.mapper.selectClockSettingsViewByUserID(userId);
        return clockSettingsView;
    }

    /**
     * @方法名：selectAttendanceManagementByUserId
     * @描述： 根据用户id查询考情管理设置
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/23 23:34
     */
    public AttendanceManagement selectAttendanceManagementByUserId(String userId) {
        AttendanceManagement management = this.mapper.selectAttendanceManagementByUserId(userId);
        return management;
    }

    /**
     * @方法名：selectManagementIdByUserId
     * @描述： 根据用户id查询考勤管理id
     * @作者： Kuang.JiaZhuo
     * @日期： Created in 2019/11/24 16:12
     */
    public String selectManagementIdByUserId(String userId) {
        String managementId = this.mapper.selectManagementIdByUserId(userId);
        return managementId;
    }


}
